package com.tangly.codeing.controller;

import com.tangly.codeing.annotation.Log;
import com.tangly.codeing.model.SysPrivilege;
import com.tangly.codeing.model.SysRole;
import com.tangly.codeing.model.SysUser;
import com.tangly.codeing.model.dto.SysUserDto;
import com.tangly.codeing.model.vo.SysUserVo;
import com.tangly.codeing.oss.OSSFactory;
import com.tangly.codeing.service.SysPrivilegeService;
import com.tangly.codeing.service.SysRoleService;
import com.tangly.codeing.service.SysUserService;
import com.tangly.codeing.utils.JWT;
import com.tangly.codeing.utils.PageInfo;
import com.tangly.codeing.utils.ReturnT;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.springframework.beans.BeanUtils;
import org.springframework.util.ClassUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 后台用户表
 *
 * @author tangbing
 * @date 2019-04-28
 */
@Api(value = "SysUserController", description = "后台用户表")
@RestController
@RequestMapping("sysUser")
public class SysUserController extends BaseController {

    @Resource
    private SysUserService sysUserService;
    @Resource
    private SysRoleService sysRoleService;
    @Resource
    private SysPrivilegeService sysPrivilegeService;

    /**
     * 新增
     */
    @PostMapping("/insert")
    public ReturnT<String> insert(@RequestBody SysUser sysUser) {
        return sysUserService.insert(sysUser);
    }

    /**
     * 删除
     */
    @GetMapping("/delete/{id}")
    public ReturnT<String> delete(@PathVariable("id") int id) {
        return sysUserService.delete(id);
    }

    /**
     * 批量删除
     */
    @GetMapping("/batchDelete")
    public ReturnT<String> batchDelete(@RequestParam("ids") String ids) {
        String[] split = ids.split(",");
        return sysUserService.batchDelete(Arrays.asList(split));
    }

    /**
     * 更新
     */
    @PostMapping("/update")
    public ReturnT<String> update(@RequestBody @Validated SysUserDto sysUserDto, BindingResult result) {
        if (result.hasErrors()) {
            FieldError fieldError = result.getFieldError();
            return new ReturnT<>(ReturnT.FAIL_CODE, fieldError.getDefaultMessage());
        }
        if (sysUserDto.getRoleList().size() == 0) {
            return new ReturnT<>(ReturnT.FAIL_CODE, "用户角色不能为空");
        }
        return sysUserService.update(sysUserDto);
    }

    /**
     * Load查询
     */
    @GetMapping("/load/{id}")
    public ReturnT<Object> load(@PathVariable("id") int id) {
        return new ReturnT<>(sysUserService.load(id));
    }

    /**
     * 分页查询
     */
    @PostMapping("/pageList")
    public ReturnT<Object> pageList(@RequestBody PageInfo pageInfo, @RequestHeader(value = "Authorization", required = true) String token) {
        String uuid = JWT.unsign(token, String.class);
        System.out.println(uuid);
        ReturnT<Object> validateRes = validateParam(pageInfo);
        if (validateRes != null) {
            return validateRes;
        }
        return new ReturnT<>(sysUserService.pageList(pageInfo));
    }

    /**
     * 用户登录
     */
    @ApiOperation(value = "登录", notes = "用户登录入参如下\n" +
            "```\n" +
            "{\n" +
            "    \"loginName\": \"账号\",\n" +
            "    \"password\": \"密码\"\n" +
            "}\n" +
            "```\n")
    @ApiImplicitParam(name = "pageInfo", value = "```\n" +
            "{\n\"whereMap\":\n" +
            "   {\n" +
            "       \"loginName\": \"admin\",\n" +
            "       \"password\": \"123456\"\n" +
            "   }\n" +
            "}" +
            "```\n", required = true, dataType = "PageInfo")
    @Log("用户登录")
    @PostMapping("/login")
    public ReturnT<Object> login(@RequestBody PageInfo pageInfo) {
        ReturnT<Object> validateRes = validateParam(pageInfo);
        if (validateRes != null) {
            return validateRes;
        }
        if (pageInfo.getWhereMap().get("loginName") == null) {
            return new ReturnT<>(ReturnT.FAIL_CODE, "登录账号不能为空");
        }
        if (pageInfo.getWhereMap().get("password") == null) {
            return new ReturnT<>(ReturnT.FAIL_CODE, "登录密码不能为空");
        }
        List<SysUser> userList = sysUserService.findAll(pageInfo);
        if (CollectionUtils.isNotEmpty(userList) && userList.size() == 1) {
            SysUser sysUser = userList.get(0);
            SysUserVo sysUserVo = new SysUserVo();
            BeanUtils.copyProperties(sysUser, sysUserVo);
            // 生成token
            String token = JWT.sign(sysUserVo.getUuid(), ReturnT.TOKEN_INDATE);
            sysUserVo.setToken(token);
            return new ReturnT<>(sysUserVo);
        }
        return new ReturnT<>(ReturnT.FAIL_CODE, "登录失败");
    }

    /**
     * 上传头像（流程：在用户新增或编辑页面选择图片后，触发上传接口，此时本接口进行云存储上传，上传成功返回图片公网地址给前端，前端保存该值，然后进行之后操作）
     */
    @RequestMapping("/upload")
    public ReturnT<String> upload(@RequestParam("file") MultipartFile file) throws Exception {
        if (file.isEmpty()) {
            return new ReturnT<>(ReturnT.FAIL_CODE, "上传文件不能为空");
        }
        // 上传文件得到文件地址
        String url = Objects.requireNonNull(OSSFactory.build()).upload(file);
        return new ReturnT<>(url);
    }

    /**
     * 根据token获取用户角色和菜单
     */
    @GetMapping("/info")
    public ReturnT<Object> info(@RequestHeader(value = "Authorization", required = true) String token) {
        String uuid = JWT.unsign(token, String.class);
        SysUser sysUser = sysUserService.findByUuid(uuid);
        List<SysRole> roleList = sysRoleService.getByUserId(Integer.parseInt(sysUser.getId().toString()));
        List<String> roles = roleList.stream().map(SysRole::getName).collect(Collectors.toList());
        List<Long> roleIds = roleList.stream().map(SysRole::getId).collect(Collectors.toList());
        List<SysPrivilege> sysPrivilegeList = sysPrivilegeService.findByRoleIds(roleIds);
        List<String> perms = sysPrivilegeList.stream().map(SysPrivilege::getUrl).collect(Collectors.toList());
        Map<String, Object> result = new HashMap<>(3);
        result.put("perms", perms);
        result.put("roles", roles);
        return new ReturnT<>(result);
    }
}
